package com.asen.commons.core.meta.entity;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 实体属性基本信息
 *
 * @author ls
 * @version 1.0
 * @date 2024-04-09
 */
public class EntityField {

    /**
     * 属性名
     */
    private String name;

    /**
     * 属性
     */
    private Field field;

    /**
     * 类型
     */
    private Class<?> javaType;

    private Type[] actualParameterTypeArgs;

    public EntityField(Field field) {
        this.field = field;
        this.name = field.getName();
        this.javaType = field.getType();
    }

    public Object getValue(Object model) throws Exception {
        if (!field.isAccessible()) {
            field.setAccessible(true);
        }
        return field.get(model);
    }

    public void setValue(Object model, Object fieldValue) throws Exception {
        if (Boolean.class.isAssignableFrom(this.javaType)) {
            if (fieldValue instanceof Integer) {
                if (new Integer(1).equals(fieldValue)) {
                    fieldValue = Boolean.TRUE;
                } else {
                    fieldValue = Boolean.FALSE;
                }
            }
        }

        if (Integer.class.isAssignableFrom(this.getJavaType())) {
            if (fieldValue instanceof Boolean) {
                if (Boolean.TRUE.equals(fieldValue)) {
                    fieldValue = new Integer(1);
                } else {
                    fieldValue = new Integer(0);
                }
            }
        }

        if (!field.isAccessible()) {
            field.setAccessible(true);
        }

        field.set(model, fieldValue);
    }

    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
        return field.isAnnotationPresent(annotationClass);
    }

    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
        return field.getAnnotation(annotationClass);
    }

    public Type[] getActualParameterTypeArgs() throws Exception {
        if (actualParameterTypeArgs != null) {
            return actualParameterTypeArgs;
        }

        if (field.getGenericType() == null) {
            return null;
        }

        if (field.getGenericType() instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
            if (parameterizedType != null) {
                actualParameterTypeArgs = (Type[]) parameterizedType.getActualTypeArguments();
                return actualParameterTypeArgs;
            }
        }

        return null;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Field getField() {
        return field;
    }

    public void setField(Field field) {
        this.field = field;
    }

    public Class<?> getJavaType() {
        return javaType;
    }

    public void setJavaType(Class<?> javaType) {
        this.javaType = javaType;
    }

    @Override
    public String toString() {
        return "EntityField{" +
                "name='" + name + '\'' +
                ", field=" + field +
                ", javaType=" + javaType +
                '}';
    }
}
